package tech.yangzhijie.blog.admin.config.authentication;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import tech.yangzhijie.blog.admin.entity.SystemRole;
import tech.yangzhijie.blog.admin.entity.SystemUser;
import tech.yangzhijie.blog.admin.entity.SystemUserRole;
import tech.yangzhijie.blog.admin.service.SystemUserRoleService;
import tech.yangzhijie.blog.admin.service.SystemUserService;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 探险家劫
 * @Date: 2021/11/18 21:15
 */
@Component
public class SecurityUserDetailsService implements UserDetailsService {

    private final SystemUserService systemUserService;
    private final SystemUserRoleService systemUserRoleService;

    public SecurityUserDetailsService(SystemUserService systemUserService, SystemUserRoleService systemUserRoleService) {
        this.systemUserService = systemUserService;
        this.systemUserRoleService = systemUserRoleService;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SystemUser systemUser = systemUserService.getOne(Wrappers.<SystemUser>lambdaQuery().eq(SystemUser::getUsername, username));
        if(systemUser == null){
            throw new UsernameNotFoundException(username);
        }

        List<SystemRole> systemRoles = systemUserRoleService.selectRoleListByUserId(systemUser.getId());
        List<SimpleGrantedAuthority> authorities = systemRoles.stream().map(role -> new SimpleGrantedAuthority(role.getCode())).collect(Collectors.toList());
        return SecurityUser.builder()
                .username(systemUser.getUsername())
                .password(new BCryptPasswordEncoder().encode(systemUser.getPassword()))
                .enabled(systemUser.getStatus() == 1)
                .authorities(authorities)
                .build();
    }
}
